package com.bj58.mis.apm.server.statistics.controller;

import com.bj58.mis.apm.server.core.common.result.Page;
import com.bj58.mis.apm.server.core.common.result.ResultBean;
import com.bj58.mis.apm.server.core.util.WOSClient;
import com.bj58.mis.apm.server.statistics.dto.chart.ChartData;
import com.bj58.mis.apm.server.statistics.dto.query.QueryDataGridItem;
import com.bj58.mis.apm.server.statistics.dto.query.Statistics;
import com.bj58.mis.apm.server.statistics.dto.rowkey.RowkeyStats;
import com.bj58.mis.apm.server.statistics.service.QueryService;
import com.bj58.mis.apm.server.statistics.service.RowkeyStatsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/query")
@Api(tags = "查询相关API", description = "/query")
public class QueryController extends BaseController<QueryService> {

    @Resource
    private RowkeyStatsService rowkeyStatsService;

    @Resource
    private WOSClient wosClient;

    @ApiOperation(value = "查询总体统计信息!", notes = "查询概览")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "项目ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "cubeId", value = "Cube ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", paramType = "query", required = true, dataType = "String")
    })
    @GetMapping(path = "/statistics")
    public ResultBean<Statistics> statistics(@RequestParam(name = "projectId", required = false) String projectId, @RequestParam(name = "cubeId", required = false) String cubeId, @RequestParam(name = "startDate", required = true) String startDate, @RequestParam(name = "endDate", required = true) String endDate) {
        String username = this.getLoginUserName();
        return ResultBean.success(this.service.statistics(username, projectId, cubeId, startDate, endDate));
    }


    @ApiOperation(value = "查询次数图表展示", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "项目ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "cubeId", value = "Cube ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", paramType = "query", required = true, dataType = "String")
    })
    @GetMapping(path = "/chart/queryCount")
    public ResultBean<ChartData> queryCount(@RequestParam(name = "projectId", required = false) String projectId, @RequestParam(name = "cubeId", required = false) String cubeId, @RequestParam(name = "startDate", required = true) String startDate, @RequestParam(name = "endDate", required = true) String endDate) {
        String username = this.getLoginUserName();
        return ResultBean.success(this.service.queryCount(username, projectId, cubeId, startDate, endDate));
    }


    @ApiOperation(value = "查询响应时间分布饼图、面积图展示", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "项目ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "cubeId", value = "Cube ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", paramType = "query", required = true, dataType = "String")
    })
    @GetMapping(path = "/chart/queryTimeData")
    public ResultBean<ChartData> queryTimeData(@RequestParam(name = "projectId", required = false) String projectId, @RequestParam(name = "cubeId", required = false) String cubeId, @RequestParam(name = "startDate", required = true) String startDate, @RequestParam(name = "endDate", required = true) String endDate) {
        String username = this.getLoginUserName();

        return ResultBean.success(this.service.queryTimeData(username, projectId, cubeId, startDate, endDate));
    }


    @ApiOperation(value = "响应时间趋势图表展示", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "项目ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "cubeId", value = "Cube ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", paramType = "query", required = true, dataType = "String")
    })
    @GetMapping(path = "/chart/queryResponseTime")
    public ResultBean<ChartData> queryResponseTime(@RequestParam(name = "projectId", required = false) String projectId, @RequestParam(name = "cubeId", required = false) String cubeId, @RequestParam(name = "startDate", required = true) String startDate, @RequestParam(name = "endDate", required = true) String endDate) {
        String username = this.getLoginUserName();

        return ResultBean.success(this.service.queryPercentile(username, projectId, cubeId, startDate, endDate));
    }


    @ApiOperation(value = "查询列表", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "项目ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "cubeId", value = "Cube ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "owner", value = "用户名", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "state", value = "状态.1表示成功.0表示失败.", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "searchKey", value = "搜索关键字.搜索项目或者cube的名称.", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "orderBy", value = "排序字段.可以按照queryCount查询次数,lastOpTime最近操作时间,maxSlowQueryTime最慢响应时间排序.默认是maxSlowQueryTime", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "sort", value = "排序方向.asc或者desc.默认是desc", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "page", value = "当前页码", defaultValue = "1", paramType = "query", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "limit", value = "每页条数", defaultValue = "10", paramType = "query", required = true, dataType = "Integer")
    })
    @GetMapping(path = "/datagrid/queryDataGrid")
    public ResultBean<Page<QueryDataGridItem>> queryDataGrid(@RequestParam(name = "projectId", required = false) String projectId, @RequestParam(name = "cubeId", required = false) String cubeId, @RequestParam(name = "startDate", required = true) String startDate, @RequestParam(name = "endDate", required = true) String endDate, @RequestParam(name = "owner", required = false) String owner, @RequestParam(name = "state", required = false) String state, @RequestParam(name = "searchKey", required = false) String searchKey, @RequestParam(name = "orderBy", required = false) String orderBy, @RequestParam(name = "sort", required = false) String sort, @RequestParam(name = "page", required = true) Integer page, @RequestParam(name = "limit", required = true) Integer limit) {
        String username = this.getLoginUserName();
        //如果前端传输空串,则替换为null
        if(state!=null && state==""){
            state=null;
        }
        return ResultBean.success(this.service.queryDataGrid(username, projectId, cubeId, startDate, endDate, owner, state, searchKey, orderBy, sort, page, limit));
    }


    @ApiOperation(value = "查询列表详细内容", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "md5", value = "cubeId和sql的md5值", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", paramType = "query", required = true, dataType = "String")
    })
    @GetMapping(path = "/datagrid/queryDataGridItem")
    public ResultBean<QueryDataGridItem> queryDataGridItem(@RequestParam(name = "md5", required = false) String md5, @RequestParam(name = "startDate", required = true) String startDate, @RequestParam(name = "endDate", required = true) String endDate,@RequestParam(name = "state", required = true) String state) {
        //如果前端传输空串,则替换为null
        if(state!=null && state==""){
            state=null;
        }
        return ResultBean.success(this.service.queryDataGridItem(md5, startDate, endDate,state));
    }

    @ApiOperation(value = "查询历史图表显示数据", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "md5", value = "cubeId和sql的md5值", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "state", value = "状态.1表示成功.0表示失败.", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", paramType = "query", required = true, dataType = "String")
    })
    @GetMapping(path = "/chart/queryHistory")
    public ResultBean<ChartData> queryHistory(@RequestParam(name = "md5", required = false) String md5, @RequestParam(name = "state", required = false) String state, @RequestParam(name = "startDate", required = true) String startDate, @RequestParam(name = "endDate", required = true) String endDate) {
        String username = this.getLoginUserName();

        return ResultBean.success(this.service.queryHistory(md5, state, startDate, endDate));
    }

    /**
     * 查询指定rowkey的使用情况，取单条日志进行计算
     *
     * @param md5
     * @return
     */
    @ApiOperation(value = "rowkey使用情况!", notes = "查询指定rowkey的使用情况")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "md5", value = "log表中间生成字段", paramType = "query", required = false, dataType = "String")
    })
    @GetMapping(path = "/rowkeyStats")
    public ResultBean<Map<String, Object>> getRowkeyStats(@RequestParam(name = "md5", required = false) String md5) {
        Map<String, Object> resultMap = new HashMap<>();
        List<RowkeyStats> list = rowkeyStatsService.getRowkeyStatsByMd5(md5);
        resultMap.put("originalData", list);
        List<Map<String, Object>> resultList = groupByStatus(list);
        resultMap.put("groupData", resultList);
        return ResultBean.success(resultMap);
    }

    private List<Map<String, Object>> groupByStatus(List<RowkeyStats> list) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String[] typeNames = {"过滤", "GroupBy", "过滤&GroupBy", "出现", "缺陷"};
        for(String tn : typeNames){
            Map<String, Object> map = new HashMap<>();
            map.put("typeName", tn);
            map.put("rowkeys", new ArrayList<RowkeyStats>());
            resultList.add(map);
        }

        if(list != null && list.size() > 0) {
            list.forEach(rs -> {
                ((List)resultList.get(Integer.parseInt(rs.getStatus()) - 1).get("rowkeys")).add(rs);
            });
        }
        return resultList;
    }

    /**
     * 返回日志信息
     * @param queryId
     * @param md5
     * @param state
     * @param startDate
     * @param endDate
     * @return
     */
    @GetMapping(path="/log/output")
    public ResultBean<String> getLogOutput(@RequestParam(name = "queryId", required = false) String queryId,
                                           @RequestParam(name = "md5", required = false) String md5,
                                           @RequestParam(name = "state", required = false) String state,
                                           @RequestParam(name = "startDate", required = false) String startDate,
                                           @RequestParam(name = "endDate", required = false) String endDate) {
        String output = "";
        if(StringUtils.isNotEmpty(queryId)){
            output = getOutput(queryId);
        }else if(StringUtils.isNotEmpty(md5) && StringUtils.isNotEmpty(startDate) && StringUtils.isNotEmpty(endDate)) {
            ChartData cd = this.service.queryHistory(md5, state, startDate, endDate);
            List<Map<String, ?>> list = (List<Map<String, ?>>) cd.getOriginalDatas();
            int len = list.size();
            for (int index = 1; len - index >= 0 && index <= 5; index ++) {
                Map<String, ?> map = list.get(len - index);
                String fileName = (String) map.get("query_id");
                output = getOutput(fileName);
                if (StringUtils.isNotEmpty(output)) {
                    break;
                }
            }
        }
        return ResultBean.success(output);

    }

    private String getOutput(String fileName){
        String output;
        try {
            output = wosClient.downloadFile(fileName);
            if (output.startsWith("<!DOCTYPE html PUBLIC")) {
                output = "";
            }
        } catch (Exception e) {
            output = "";
        }
        return output;
    }
}
